package org.example.config;

import jakarta.annotation.Resource;
import org.example.dto.UserDto;
import org.example.service.UserService;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.stream.Collectors;


@Component
public class LoginReactiveAuthenticationManager implements ReactiveAuthenticationManager {
  @Resource
  private  PasswordEncoder passwordEncoder;     //密码验证的编码器
    @Resource private  UserService userService;            //负责根据用户名查找用户
    @Override
    public Mono<Authentication> authenticate(Authentication authentication) {
        String account = authentication.getName();
        String password = (String) authentication.getCredentials();
        // 1. 通过用户名查找用户
       UserDto userDto = userService.findByUsername(account);
        // 2. 验证密码
       if (userDto != null && passwordEncoder.matches(password,userDto.getPassword())){
           // 3. 构建已认证的Authentication对象（包含权限）
           List<GrantedAuthority> authorities = userDto.getAuthorities().stream()
                   .map(auth -> new SimpleGrantedAuthority(auth))
                   .collect(Collectors.toList());
           return Mono.just(new UsernamePasswordAuthenticationToken(
                   account,       // 用户名
                   null,          // 认证后密码不再需要，设为 null
                   authorities));  // 用户权限列表
       }
        // 4. 认证失败，抛出异常
        return Mono.error(new BadCredentialsException("用户名或密码错误！"));
    }
}
